require'zdc.nodeapi'
require'zdc.idutil'
require'zdc.logger'
require'zdc.dal'
require'zdc.gim'

local asynccall=zdc.nodeapi.asynccall

module(..., package.seeall)

local Appbase = {}
local Appbase_mt = {__metatable = {}, __index = Appbase}

zdc.dal.MakeInhMT(Appbase)

function MakeInhMT(ch)
	ch=ch or {}
	for _i,_j in pairs(Appbase) do
		ch[_i]=_j
	end
	return ch
end


function new(config, logger,childmt)
	if config._dal then return config._dal end
	local obj=zdc.dal.new(config.gim or zdc.gim.new(),config.gimsvc or zdc.gim.new(),logger,childmt or Appbase_mt)
	obj:Init(config)
	return obj
end

function Appbase:Init(config)
	config._dal=self
	self._bak_config=config
	self.dal=self
	self.APP=self
	self.auth=config.auth
	self.DALCFG=config.DALCFG
	zdc.dal.InitDAL(self,config.dpl,config.dplsvc,config.sbenv,self.logger)
	if not config.NOCONFIG and config.CONFIG_NAME then
		local config_node = self.dal:SureNode(config.CONFIG_NAME)
		assert(config_node,"can't load config node: " .. config.CONFIG_NAME)
		local new_config = config_node.content or {}
		assert(new_config and type(new_config)=="table","Config node's content should evaluate to a table")
		if config.sbenv then
			self.config = setmetatable({}, {__index = setmetatable(new_config, {__index=config.sbenv})})
		else
			self.config = setmetatable({}, {__index = new_config})
		end
	else
		if config.sbenv then
			self.config = setmetatable({}, {__index = config.sbenv})
		else
			self.config={}
		end
	end
end

--[[
request{
user: the user id
node: the node name for action
act: the action name
args{}: the args for action 
}
--]]
function Appbase:HandleRequest(chinfo,request,respone)
	local dal=self.dal
	local user,nid,act=chinfo.accid,request.node,request.act
	if not user then user='' end
	--dal.AUTHUSER=user
	
	if not act or #act ==0 then
		respone.ret={nil,'no act arg'}
		return respone
	else
		local node,msg=dal:GetNode(nid)
		if not node then respone.ret={false,'node not exist'};return respone end
		respone.ret={select(2,assert(zdc.nodeapi.callact(user,dal,node,act,request.args)))}
		--if dal.AUTHUSER~=user then
		--	chinfo.accid=dal.AUTHUSER or ''
		--end
		return respone
	end
end

function Appbase:HandleRequestCB(chinfo,request,cb)
	local dal=self.dal
	local user,nid,act=chinfo.accid,request.node,request.act
	if not user then user='' end
	--dal.AUTHUSER=user
	
	if not act or #act ==0 then
		cb(nil,'no act arg')
	else
		local node,msg=dal:GetNode(nid)
		if not node then
			cb(nil,'node not exist:'..tostring(nid)) 
			return
		end
		local r,msg=asynccall(user,dal,cb,node,act,request.args)
		if not r then cb(r,msg) end
	end
end